import java.io.*;
import java.net.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import com.aliasi.tokenizer.*;
import com.aliasi.symbol.*;
import com.aliasi.corpus.ObjectHandler;
import com.aliasi.util.ObjectToCounterMap;
import com.aliasi.util.Strings;
import com.aliasi.stats.Statistics;

public class GeocoderService extends HttpServlet {

	private Geocoder model;

	private static final long serialVersionUID = -9186875057311859285L;

	{
		System.setProperty("javax.xml.parsers.DocumentBuilderFactory",
		"org.apache.xerces.jaxp.DocumentBuilderFactoryImpl");
		System.setProperty("javax.xml.parsers.SAXParserFactory",
		"org.apache.xerces.jaxp.SAXParserFactoryImpl");
	}

	public void init(ServletConfig servletconfig) throws ServletException {
		super.init(servletconfig);
		try {
			String modelName = servletconfig.getInitParameter("model-name");
			if ( modelName == null ) modelName = "model.classifier";
			this.model = new Geocoder( servletconfig.getServletContext().getRealPath("WEB-INF" + File.separator + modelName) );
		} catch ( Exception ex ) { throw new ServletException(ex.toString()); }
	}

	public void doGet(HttpServletRequest httpservletrequest, HttpServletResponse httpservletresponse) throws IOException {
		doPost(httpservletrequest, httpservletresponse);
	}

	public void doPost(HttpServletRequest httpservletrequest, HttpServletResponse httpservletresponse) throws IOException {
		PrintStream out = new PrintStream(httpservletresponse.getOutputStream());
		try {
			String scheme = httpservletrequest.getScheme();
			String serverName = httpservletrequest.getServerName();
			int portNumber = httpservletrequest.getServerPort();
			String contextPath = httpservletrequest.getContextPath();
			String servletPath = httpservletrequest.getServletPath();
			String pathInfo = httpservletrequest.getPathInfo();
			String auxPath = scheme + "://" + serverName + ":" + portNumber + contextPath + servletPath + pathInfo;
			httpservletresponse.setContentType("text/xml");
			String service = httpservletrequest.getParameter("service");
			String doc = httpservletrequest.getParameter("document");
			Geocoder.GeocoderResult result = model.processDocument(doc);
			if ( service.equals("geocode-htm")) {
				out.println( "<document-geocoding>" );
				out.println( " <geocode best='true'>" );
				out.println( "  <htm-code>"+ result.geocode + "</htm-code>" );
				out.println( "  <probability>" + result.probability + "</probability>" );
				out.println( " </geocode>" );
				out.println( "</document-geocoding>" );
			} else if ( service.equals("geocode")) {
				out.println( "<document-geocoding>" );
				out.println( " <geocode best='true'>" );
				out.println( "  <htm-code>"+ result.geocode + "</htm-code>" );
				out.println( "  <probability>" + result.probability + "</probability>" );
				out.println( "  <latitude>" + result.latitude + "</latitude>" );
				out.println( "  <longitude>" + result.longitude + "</longitude>" );
				out.println( " </geocode>" );
				out.println( "</document-geocoding>" );
			} else if ( service.equals("geocode-full")) {
				out.println( "<document-geocoding>" );
				out.println( " <geocode best='true'>" );
				out.println( "  <htm-code>"+ result.geocode + "</htm-code>" );
				out.println( "  <probability>" + result.probability + "</probability>" );
				out.println( "  <latitude>" + result.latitude + "</latitude>" );
				out.println( "  <longitude>" + result.longitude + "</longitude>" );
				out.println( " </geocode>" );
				for ( String geocode : result.nonZeroClassProbs.keySet() ) if ( !geocode.equals(result.geocode)) {
				out.println( " <geocode>" );
				out.println( "  <htm-code>"+ geocode + "</htm-code>" );
				out.println( "  <probability>" + result.nonZeroClassProbs.get(geocode) + "</probability>" );
				out.println( " </geocode>" );
				}
				out.println( "</document-geocoding>" );
			} else throw new Exception("Invalid input parameters.");
			out.flush();
		} catch (Exception ex) {
			out.println("<error>");
			ex.printStackTrace(out);
			out.println("</error>");
			out.flush();
		}
	}

}
